BPVC - Computational design report

1. Departments Stacking

Il primo studio riguarda l'ottimizzazione della distribuzione dei dipartimenti sui livelli dell’edificio.

Adjacencies Matrix

Compilazione della matrice delle prossimità dei dipartimenti. Oltre alla matrice vengono inserite anche le aree di programma, le aree di progetto e l’indicazione dei livelli su cui possono essere ospitati i dipartimenti.

Algoritmo generativo

L’algoritmo generativo è la componente principale di tutto il processo. E’ l’insieme di regole che consentono di creare le migliaia di opzioni, che poi verranno valutate ed esplorate nei passaggi successivi.

In questo caso è stato impostato uno script in Grasshopper in cui i valori assegnati alle variabili (sliders), generano composizioni di stacking ogni volta diverse.

Algoritmo di valutazione

Gli algoritmi di valutazione ricevono le opzioni dal generatore e, assegnando un valore, ne valutano la performance.
In questo caso vengono valutati tre parametri:

  • Unplaced area: totale di area di programma non posizionata (valore da minimizzare)
  • Adjacency: sommatoria delle prossimità positive. Per i dipartimenti posizionati sullo stesso piano vengono selezionati dalla matrice i reciproci valori di prossimità assegnando i seguenti valori numerici: A=10, B=5, D=2. (valore da massimizzare)
  • Negative Adjacency: sommatoria delle prossimità negative. (valore da minimizzare)

Generative Design Engine

Il generative design engine, chiamato anche solver, è un’applicazione software che esegue molte volte in automatico uno script, che contiene sia l’algoritmo generativo che quello valutativo.
Variando più volte la posizione degli slider, ottiene una grande quantità di opzioni diverse e le relative valutazioni. In questo caso sono stati utilizzati due metodi di generazione delle opzioni:

  • CROSS PRODUCT: consente di esplorare l’intero campo di opzioni possibili, generate da tutte le combinazioni, ottenute posizionando ogni variabile su una serie discreta di valori all’interno del loro range.
  • OPTIMIZE: consente di ottenere le opzioni con le performance migliori. algoritmo di tipo genetico (multi-objective optimization), che crea diverse “generazioni” (o iterazioni), dove ogni iterazione usa come configurazione gli input della generazione precedente associati ai risultati migliori.

    Optimize - Nella schermata si nota come l'algoritmo di ottimizzazione tenda a far convergere i valori dei parametri di valutazione verso i valori ottimali


    Cross Product - Grafico a coordinate parallele


    Cross Product - Scatter plot

Design Space Exploration (DSE)

La design space exploration (DSE) è un processo di analisi sistematica delle moltissime design option ottenute. L’obiettivo è quello di analizzare i dati per una progressiva scrematura, fino a raggiungere un numero di opzioni accettabile e rappresentativo del design space.
La DSE può essere suddivisa in diversi step, in cui il numero di opzioni viene ridotto ad ogni passaggio.

Prima fase:

Analisi dei dati eseguita con strumenti di programmazione Python e tecniche di unsupervised machine learning, che consentono di scremare le opzioni e selezionarne un numero ristretto.

In [1]:
%%javascript
$('.input').children('.inner_cell').hide();
In [2]:
# Import 
import json
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import seaborn as sns  
from sklearn import metrics  
import plotly
import plotly.graph_objects as go
import plotly.express as px

projectName = "BPVC"

# Dataframe from GD Autodesk
df = pd.read_csv('../DSE/000000-CVP-CD-01-X-DY-Departments 012.csv')
studyName = "GD012"

# Dataframe from Wallacei
#df = pd.read_excel('../DSE/BPVC-WLC Results.xlsx')
#studyName = "WLC"

df
Out[2]:
ID posAdj negAdj depLeftoverArea depsLev0 depsLev1 depsLev2 depsLev3 depsLev4 levsOrder Generation created Is solution optimal?
0 ec7a6e0e-cf2b-47cb-8816-074afe8c0bb2 231 0 1680 30734 85 213341178 261832 9223 112 1 False
1 7f9a37c2-8f9d-479d-8b5c-80cad3ffa62a 221 30 235 20250 39596 369081816 195816 34686 28 1 False
2 97491116-71ab-4c5f-82fd-4efe7eeb0c53 269 20 1565 22982 8057 241761911 175969 14385 41 1 False
3 c6b45ad6-a5e5-426e-8645-a9ad8e7e3211 251 120 0 10293 33938 322422455 30204 673 2 1 False
4 7a312607-772a-4c58-bd19-7aebe0362aa8 253 70 700 10217 19233 47962020 236615 1597 1 1 False
... ... ... ... ... ... ... ... ... ... ... ... ...
7052 8401ae45-488e-4569-9d96-fdb323262f6d 188 110 1510 15351 12076 284644459 63505 22223 4 99 False
7053 4013b2af-0c36-47ea-963e-1420fe867838 228 40 1625 18049 25743 180425924 65676 12911 5 99 False
7054 a7168528-fd4c-470d-8792-6ec0e05f5694 319 0 30 18369 27182 183461055 41811 21689 4 99 False
7055 6d7d80da-9ffa-4585-8522-907eb2912320 319 0 30 18369 27182 183461055 41811 21689 4 99 False
7056 eb39b080-b653-43db-9226-3ac9eec372a7 319 0 30 18369 27182 183461055 41811 21689 4 99 False

7057 rows × 12 columns

Gli strumenti utilizzati sono:

  • Grafico a coordinate parallele per filtrare le opzioni in base ai risultati numerici ed eliminare le peggiori.
In [3]:
fig = go.Figure(data=
    go.Parcoords(labelfont = {'family': "Arial",
                    'size': 14
                },
                line = dict(color = df['posAdj'],
                   colorscale = 'tealrose',
                   showscale = True,
                    colorbar = {'tickfont': {'size': 14
                                    
                                }
                               },
                   ),
                dimensions = list([
                    dict(label = "Adjacency", values = df['posAdj']),
                    dict(label = 'Remote', values = df['negAdj']),
                    dict(label = 'Departments Leftover Area', values = df['depLeftoverArea']),
                    
                    #dict(label = 'Levels Leftover Area', values = df['levLeftoverArea'])
                ])
                ),
                
)   

fig.show()
  • Pairplots: per analizzare eventuali correlazioni tra i parametri, sia di generazione che di valutazione.
In [4]:
df_ToCluster = df.loc[(df['posAdj'] >= 150) & (df['negAdj'] >= -80)]

df_ToCluster = df_ToCluster[['posAdj','negAdj','depLeftoverArea']]

sns.set()
sns_plot = sns.pairplot(df_ToCluster)
  • Clustering: per raggruppare opzioni con risultati simili. Selezionando un solo rappresentante per ogni cluster (centro del cluster), si ottiene un campione ridotto che sia comunque rappresentativo di tutto il design space.
In [5]:
scaler = StandardScaler()
scaled_array = scaler.fit_transform(df_ToCluster)
scaled_dataframe = pd.DataFrame( scaled_array, columns = df_ToCluster.columns )

kmeans_model = KMeans(n_clusters = 10)
kmeans_model.fit(scaled_dataframe)

df_ToCluster["cluster"] = kmeans_model.labels_
scaled_dataframe["cluster"] = kmeans_model.labels_

fig = go.Figure(data=[go.Scatter3d(
                x=df_ToCluster['posAdj'],
                y=df_ToCluster['negAdj'],
                z=df_ToCluster['depLeftoverArea'],
                mode='markers',
                marker=dict(
                    size=12,
                    color=df_ToCluster['cluster'],                # set color to an array/list of desired values
                    colorscale='geyser',   # choose a colorscale
                    opacity=0.8,
                    colorbar = {'tickvals': df_ToCluster['cluster'].tolist(),
                                  'ticktext': df_ToCluster['cluster'].tolist(),
                                'tickfont': {'size': 14},
                               },
))])
fig.update_layout(scene = dict(
                    xaxis_title='Sun Exposure',
                    yaxis_title='View to Park',
                    zaxis_title='Summer Rad RS'),
                  margin=dict(l=0, r=0, b=0, t=0))

fig.show()
In [6]:
sns.set()
sns_plot = sns.pairplot(data = df_ToCluster, hue = "cluster", palette = "Spectral")

Seconda fase:

Esplorazione delle singole opzioni

Al termine della design space exploration è possibile scegliere una o più opzioni da sviluppare nella successiva fase di space planning su ogni piano.

2. Space Planning

Dopo aver impostato lo stacking e di conseguenza il posizionamento dei dipartimenti su ogni livello, stiamo studiando un workflow che agevoli lo space planning dei piani.

1. Adjacencies Matrix (per piano)

Come già fatto per i dipartimenti, viene compilata la matrice delle adiacenze, per le funzioni di piano.

2. Bubble graph (Syntactic e Gephi)

Abbiamo sperimentato diversi metodi che generano in automatico un grafico a bolle che massimizza la vicinanza dei nodi collegati tra di loro.
Questo grafico può essere usato come riferimento per lo zoning del relativo piano.

Inoltre è possibile generare grafici delle distanze topologiche che graficizzano i vari livelli di distanza topologica, ovvero il numero di nodi per raggiungere uno spazio da un altro.
Analysis of spatial relations

Next steps

Si riportano due ulteriori metodi di space planning che abbiamo iniziato a studiare durante le nostre ricerche e che potrebbero avere degli sviluppi futuri.

1. Space Planning - Hypar



Un'ulteriore possibilità che abbiamo esplorato è di usare le funzioni Space Planning di Hypar, una nuova piattaforma che permette di generare opzioni di progetto - come ad esempio massing, strutture, stacking plan, zoning, test-fit - in maniera veloce e intuitiva. Nel caso dello space planning è possibile riconfigurare velocemente gli spazi tenendo sotto controllo l'aderenza al programma.

Hypar functions

Ciò che rende Hypar interessante rispetto ad altri programmi simili è la possibilità di impostare funzioni custom utilizzando linguaggi di programmazione o Grasshopper. Ad esempio sarebbe possibile creare funzioni custom per la creazione di layout di uffici basati su standard e stile di progettazione peculiari del nostro studio.

In [7]:
from IPython.display import HTML
HTML("""<p align="center"><iframe width="840" height="472" src="https://www.youtube.com/embed/C-nDLG3vauM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>""")
Out[7]:

2. House GAN

Uno dei tools di Intelligenza Artificiale più promettente per l’applicazione al processo di progettazione architettonica sono i GAN (Generative Advesarial Neural Networks).
I GAN sono in grado di generare immagini garantendo al contempo la precisione attraverso un ciclo di feedback autocorrettivo.

Al seguente link si riporta un esempio di GAN applicati alla generazione del layout di una residenza. La rete neurale è stata addestrata con un database composto da circa 117 mila floorplan reali. Per ogni floorplan è stato generato un bubble graph che, insieme ad una pianta vettoriale, è servito per il training della rete neurale.
L'input da utilizzare per la generazione del floorplan quindi è un bubble graph.

Link utili:
House GAN
Deep Learning-GAN

In [8]:
%%javascript
function toggler(){
    if(window.already_toggling){
        // Don't add multiple buttons.
        return 0
    }
    let btn = $('.input').append('<button>Toggle Code</button>')
        .children('button');
    $('.input').children('.inner_cell').hide();
    btn.on('click', function(e){
        let tgt = e.currentTarget;
        $(tgt).parent().children('.inner_cell').toggle()
    })
    window.already_toggling = true;
}

setTimeout(toggler, 5000);
In [9]:
!jupyter nbconvert BPVC-Report.ipynb --to html --template classic
[NbConvertApp] Converting notebook BPVC-Report.ipynb to html
[NbConvertApp] Writing 4533611 bytes to BPVC-Report.html